package com.madoka.base.web.controller;

import com.madoka.base.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.MessageSource;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.servlet.LocaleResolver;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Validator;
import java.beans.PropertyEditorSupport;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.Date;

/**
 * Base Controller
 *
 * @author Barudisshu
 */
@Slf4j
public abstract class BaseController {

    public String messageurl = "/common/message";

    public String message = "message";

    public String redirect = "redirect:";

    public String forward = "forward:";

    @Resource
    private MessageSource messageSource;
    @Resource
    private LocaleResolver localeResolver;

    @Resource
    protected Validator validator;

    /**
     * 初始化映射格式.
     *
     * @param binder 绑定
     */
    @InitBinder
    public void initBinder(WebDataBinder binder) {

        binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
            @Override
            public String getAsText() {
                Object value = getValue();
                return value != null ? (DateUtils.format((Date) value, DateUtils.YYYY_MM_DD)) : "";
            }

            @Override
            public void setAsText(String text) {
                if (StringUtils.isNotEmpty(text) && text.length() <= 5) {
                    setValue(DateUtils.formatTimeNoSs(text));
                } else if (StringUtils.isNotEmpty(text) && text.length() <= 8) {
                    setValue(DateUtils.formatTime(text));
                } else if (StringUtils.isNotEmpty(text) && text.length() <= 10) {
                    setValue(DateUtils.formatNoTime(text));
                } else if (StringUtils.isNotEmpty(text) && text.length() <= 16) {
                    setValue(DateUtils.formatWithHHmm(text));
                } else if (StringUtils.isNotEmpty(text)) {
                    setValue(DateUtils.format(text));
                }
            }
        });
        binder.registerCustomEditor(Integer.class, new PropertyEditorSupport() {
            public void setAsText(String value) {
                try {
                    if (StringUtils.isNotBlank(value)) {
                        setValue(Integer.valueOf(value));
                    } else {
                        setValue(null);
                    }
                } catch (Exception e) {
                    setValue(null);
                    log.error(e.getMessage(), e);
                }
            }
        });
        binder.registerCustomEditor(Long.class, new PropertyEditorSupport() {
            public void setAsText(String value) {
                try {
                    if (StringUtils.isNotBlank(value)) {
                        setValue(Long.valueOf(value));
                    } else {
                        setValue(null);
                    }
                } catch (Exception e) {
                    setValue(null);
                    log.error(e.getMessage(), e);
                }
            }
        });
        binder.registerCustomEditor(Double.class, new PropertyEditorSupport() {
            public void setAsText(String value) {
                try {
                    if (StringUtils.isNotBlank(value)) {
                        setValue(Double.valueOf(value));
                    } else {
                        setValue(null);
                    }
                } catch (Exception e) {
                    setValue(null);
                    log.error(e.getMessage(), e);
                }
            }
        });

        binder.registerCustomEditor(BigDecimal.class, new PropertyEditorSupport() {
            public void setAsText(String value) {
                try {
                    if (StringUtils.isNotBlank(value)) {
                        setValue(new BigDecimal(value));
                    } else {
                        setValue(null);
                    }
                } catch (Exception e) {
                    setValue(null);
                    log.error(e.getMessage(), e);
                }
            }
        });
    }

    @ExceptionHandler
    public String exp(HttpServletRequest request, Exception e) {
        e.printStackTrace();
        request.setAttribute("e", e);
        log.error(e.getMessage(), e);
        return "/error";
    }

    /**
     * 公共下载方法
     *
     * @param response 响应
     * @param file     下载的文件
     * @param fileName 下载时显示的文件名
     * @throws Exception
     */
    public HttpServletResponse downFile(HttpServletResponse response, File file, String fileName, boolean delFile)
            throws Exception {
        response.setContentType("application/x-download");
        response.setHeader("Pragma", "public");
        response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
        OutputStream out = null;
        InputStream in = null;
        // 下面一步不可少
        fileName = new String(fileName.getBytes("GBK"), "ISO-8859-1");
        response.addHeader("Content-disposition", "attachment;filename=" + fileName);// 设定输出文件头

        try {
            out = response.getOutputStream();
            in = new FileInputStream(file);
            int len = in.available();
            byte[] b = new byte[len];
            in.read(b);
            out.write(b);
            out.flush();

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new Exception("下载失败!");
        } finally {
            if (in != null) {
                in.close();
            }
            if (out != null) {
                out.close();
            }
            if (delFile) {
                file.delete();
            }
        }
        return response;
    }
}
